package com.yeebo.interceptor;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Enumeration;

/**
 * 通用拦截器
 */
public class CommonInterceptor extends HandlerInterceptorAdapter {
    private static Logger logger = LoggerFactory.getLogger(CommonInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
        //允许跨域,不能放在postHandle内
        response.addHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,PATCH");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, Token, x-requested-with, token");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

        String requestMethod = request.getMethod();
        if ("GET".equalsIgnoreCase(requestMethod)) {
            logger.info("收到请求地址【{}】请求方式【{}】请求数据【{}】",
                    request.getRequestURI(), requestMethod, getFormDataStr(request));
        } else {
            String contentType = request.getHeader("content-type");
            if (StringUtils.isNotBlank(contentType)) {
                if (contentType.contains("multipart/form-data") || contentType.contains("application/x-www-form-urlencoded")) {
                    logger.info("收到请求地址【{}】请求方式【{}】请求FORM数据【{}】",
                            request.getRequestURI(), requestMethod, getFormDataStr(request));
                } else if (contentType.contains("text/xml")) {
                    logger.info("收到请求地址【{}】请求方式【{}】请求数据类型【{}】请求FORM数据【{}】请求体数据【{}】",
                            request.getRequestURI(), requestMethod, contentType, getFormDataStr(request), getPostXmlStr(request));
                } else {
                    logger.info("收到请求地址【{}】请求方式【{}】请求数据类型【{}】请求FORM数据【{}】请求体数据【{}】",
                            request.getRequestURI(), requestMethod, contentType, getFormDataStr(request),
                            getPostJsonStr(new RequestReaderHttpServletRequestWrapper(request)));
                }
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) {
        // 请求之后调用，在视图渲染之前，也就是Controller方法调用之后
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        // 请求结束之后被调用，主要用于清理工作
    }

    public static String getPostJsonStr(HttpServletRequest request) {
        String param = null;
        try {
            BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);

            JSONObject jsonObject = JSONObject.parseObject(responseStrBuilder.toString());
            param = jsonObject != null ? jsonObject.toJSONString() : null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return param;
    }

    private String getPostXmlStr(HttpServletRequest request) {
        String param = null;
        try {
            BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);

            param = responseStrBuilder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return param;
    }

    private String getFormDataStr(HttpServletRequest request) {
        Enumeration<String> e = request.getParameterNames();
        StringBuilder params = new StringBuilder();
        while (e.hasMoreElements()) {
            String name = e.nextElement();
            params.append(name).append("=").append(request.getParameter(name)).append(";");
        }
        return params.toString();
    }

}
